
package com.gcloud.mesh.dcs.controller;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.DictCode;
import org.jeecg.common.constant.enums.SysLogOperateType;
import org.jeecg.common.constant.enums.SysLogType;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.gcloud.framework.db.PageResult;
import com.gcloud.mesh.dcs.annotation.ParamSecurity;
import com.gcloud.mesh.dcs.entity.SchedulerJobEntity;
import com.gcloud.mesh.dcs.enums.SchedulerJobStatus;
import com.gcloud.mesh.dcs.service.AppService;
import com.gcloud.mesh.dcs.service.SchedulerAdviceService;
import com.gcloud.mesh.dcs.service.SchedulerService;
import com.gcloud.mesh.header.msg.dcs.AviableDatacenterMsg;
import com.gcloud.mesh.header.msg.dcs.PageDatacenterSchedulerConfigMsg;
import com.gcloud.mesh.header.msg.dcs.PageInstanceMsg;
import com.gcloud.mesh.header.msg.dcs.PageSchedulerAdviceMsg;
import com.gcloud.mesh.header.msg.dcs.PageSchedulerJobMsg;
import com.gcloud.mesh.header.msg.dcs.PageSchedulerStepMsg;
import com.gcloud.mesh.header.msg.dcs.SchedulerEffectPredictionMsg;
import com.gcloud.mesh.header.msg.dcs.SchedulerResultAnalysisMsg;
import com.gcloud.mesh.header.msg.dcs.StartJobMsg;
import com.gcloud.mesh.header.msg.dcs.UpdateSchedulerModelMsg;
import com.gcloud.mesh.header.msg.dcs.UpdateSchedulerModelToolMsg;
import com.gcloud.mesh.header.msg.dcs.UpdateSchedulerStrategyConfigMsg;
import com.gcloud.mesh.header.msg.dcs.UpdateSchedulerStrategyRuleMsg;
import com.gcloud.mesh.header.vo.dcs.AppInstanceVo;
import com.gcloud.mesh.header.vo.dcs.DatacenterResourceVo;
import com.gcloud.mesh.header.vo.dcs.DatacenterSchedulerConfigVo;
import com.gcloud.mesh.header.vo.dcs.MigrateResourceVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerAdviceVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerEffectPredictionVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerJobVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerModelToolVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerModelVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerOverview;
import com.gcloud.mesh.header.vo.dcs.SchedulerResultAnalysisVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerStepVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerStrategyConfigVo;
import com.gcloud.mesh.header.vo.dcs.SchedulerStrategyRuleVo;
import com.gcloud.mesh.header.vo.dcs.UpdateSchedulerVo;
import com.gcloud.mesh.supplier.enums.SystemType;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api(tags = "调度管理")
@RestController
@RequestMapping("/scheduler")
public class SchedulerController {

	@Autowired
	private SchedulerService service;
	
	@Autowired
	private SchedulerAdviceService adviceService;
	
	@Autowired
	private ISysBaseAPI sysBaseAPI;


	// 处理Mass Assignment: Insecure Binder Configuration
	@InitBinder
	public void populateCustomerRequest(WebDataBinder binder) {
		binder.setDisallowedFields(new String[] {});
	}

	// @AutoLog(value = "查询调度任务列表", operateType = CommonConstant.OPERATE_TYPE_LIST, module = "")
	@ApiOperation(value = "调度任务列表", notes = "调度任务列表")
	@RequestMapping(value = "/job/page", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerJobPage" })
	@ParamSecurity(enabled = true)
	public PageResult<SchedulerJobVo> jobPage(@Valid PageSchedulerJobMsg msg) throws Exception {
		PageResult<SchedulerJobVo> res = this.service.jobPage(msg);
		if(StringUtils.isNotBlank(msg.getTitle())) {
			sysBaseAPI.addLog(msg.getContent() != null?msg.getContent():"查询调度任务列表", null, SysLogOperateType.QUERY, null, null, msg.getTitle());
		}
		return res;
	}

	// @AutoLog(value = "查询调度步骤列表", operateType = CommonConstant.OPERATE_TYPE_LIST, module = "多数据中心调度-动态调度机制-调度过程监控")
	@ApiOperation(value = "调度步骤列表", notes = "调度步骤列表")
	@RequestMapping(value = "/step/list1", method = RequestMethod.POST)
	// @RequiresPermissions(value = {"schedulerSteplist"})
	@ParamSecurity(enabled = true)
	public List<SchedulerStepVo> stepPage(@Valid PageSchedulerStepMsg msg) throws Exception {
		List<SchedulerStepVo> res = this.service.stepList(msg);
		sysBaseAPI.addLog("查询调度步骤列表，调度任务ID："+msg.getSchedulerJobId(), null, SysLogOperateType.QUERY, null, null, "多数据中心调度-动态调度机制-调度过程监控");
		return res;
	}

	@AutoLog(value = "查询调度触发策略设置列表", operateType = CommonConstant.OPERATE_TYPE_LIST, module = "多数据中心调度-动态调度机制-调度触发策略设置")
	@ApiOperation(value = "调度配置列表", notes = "调度配置列表")
	@RequestMapping(value = "/datacenter_config/page", method = RequestMethod.POST)
	@ParamSecurity(enabled = true)
	public PageResult<DatacenterSchedulerConfigVo> datacenterConfigPage(@Valid PageDatacenterSchedulerConfigMsg msg) throws Exception {
		PageResult<DatacenterSchedulerConfigVo> res = this.service.datacenterConfigPage(msg);
		return res;
	}

	// @AutoLog(value = "设置多数据中心调度对象力度", operateType = CommonConstant.OPERATE_TYPE_CONFIG)
	@ApiOperation(value = "多数据中心调度对象力度设置", notes = "多数据中心调度对象力度设置")
	@RequestMapping(value = "/update_scheduler1", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerUpdate_scheduler" })
	@ParamSecurity(enabled = true)
	public void updateScheduler(@Valid UpdateSchedulerVo msg) throws Exception {
		this.service.updateScheduler(msg);
		// service.updateSchedulerModel(type);
		StringBuffer buff = new StringBuffer();
    	buff.append("设置多数据中心调度对象粒度");
    	buff.append(","+msg.toString());
		sysBaseAPI.addLog(buff.toString(), null, SysLogOperateType.UPDATE);
	}

	@AutoLog(value = "查看调度策略设置", operateType = CommonConstant.OPERATE_TYPE_DETAIL)
	@ApiOperation(value = "调度策略列表", notes = "调度策略列表")
	@RequiresPermissions(value = { "schedulerScheduler_model_list" })
	@RequestMapping(value = "/scheduler_model_list", method = RequestMethod.GET)
	@ParamSecurity(enabled = true)
	public List<SchedulerModelVo> schedulerModelList() throws Exception {
		return service.schedulerModelList();
	}

	// @AutoLog(value = "设置调度策略", operateType = CommonConstant.OPERATE_TYPE_CONFIG)
	@ApiOperation(value = "调度策略设置", notes = "调度策略设置")
	@RequiresPermissions(value = { "schedulerUpdate_scheduler_model" })
	@RequestMapping(value = "/update_scheduler_model", method = RequestMethod.POST)
	@ParamSecurity(enabled = true)
	public void updateSchedulerModel(@Valid UpdateSchedulerModelMsg type) throws Exception {
		
		service.updateSchedulerModel(type);
		StringBuffer buff = new StringBuffer();
    	buff.append(type.toString());
		sysBaseAPI.addLog("修改调度策略，"+type.toString(), null, SysLogOperateType.UPDATE, null, null, "多数据中心调度-调度模型管理-调度策略设置");
	}

	// @AutoLog(value = "更新异步迁移模型工具", operateType = CommonConstant.OPERATE_TYPE_UPDATE, module = "离线业务多数据中心迁移-异步模型迁移工具")
	@ApiOperation(value = "异步迁移模型工具", notes = "异步迁移模型工具")
	@RequestMapping(value = "/update_scheduler_model_tool", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerUpdate_scheduler_model_tool" })
	@ParamSecurity(enabled = true)
	public void updateSchedulerModelTool(@Valid UpdateSchedulerModelToolMsg tool) throws Exception {
		service.updateSchedulerModelTool(tool);
		StringBuffer buff = new StringBuffer();
    	buff.append("更新异步迁移模型工具");
    	sysBaseAPI.addLog("配置异步迁移模型工具，"+tool.toString(), SysLogType.OPERATE, SysLogOperateType.UPDATE, null ,null ,"离线业务多数据中心迁移-异步模型迁移工具");
		// sysBaseAPI.addLog(buff.toString(), null, SysLogOperateType.UPDATE);
	}

	@AutoLog(value = "查看异步迁移模型工具", operateType = CommonConstant.OPERATE_TYPE_DETAIL, module = "离线业务多数据中心迁移-异步模型迁移工具")
	@ApiOperation(value = "异步迁移模型工具列表", notes = "异步迁移模型工具列表")
	@RequestMapping(value = "/scheduler_model_tool_list", method = RequestMethod.GET)
	@RequiresPermissions(value = { "schedulerScheduler_model_tool_list" })
	@ParamSecurity(enabled = true)
	public List<SchedulerModelToolVo> schedulerModelToolList() throws Exception {
		return service.schedulerModelToolList();
	}

	// @AutoLog(value = "配置迁移策略", operateType = CommonConstant.OPERATE_TYPE_CONFIG)
	@ApiOperation(value = "迁移策略配置", notes = "迁移策略配置")
	@RequestMapping(value = "/update_scheduler_strategy_config", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerUpdate_scheduler_strategy_config" })
	@ParamSecurity(enabled = true)
	public void updateSchedulerStrategyConfig(@Valid UpdateSchedulerStrategyConfigMsg config) throws Exception {
		service.updateSchedulerStrategyConfig(config);
		StringBuffer buff = new StringBuffer();
    	buff.append("配置迁移策略，"+config.toString());
		sysBaseAPI.addLog(buff.toString(), null, SysLogOperateType.UPDATE);
	}

	@AutoLog(value = "查看迁移策略配置", operateType = CommonConstant.OPERATE_TYPE_DETAIL)
	@ApiOperation(value = "迁移策略配置列表", notes = "迁移策略配置列表")
	@RequestMapping(value = "/scheduler_strategy_config_list", method = RequestMethod.GET)
	@RequiresPermissions(value = { "schedulerScheduler_strategy_config_list" })
	@ParamSecurity(enabled = true)
	public List<SchedulerStrategyConfigVo> schedulerStrategyConfigList() throws Exception {
		return service.schedulerStrategyConfigList();
	}

	// @AutoLog(value = "修改迁移策略执行规则", operateType = CommonConstant.OPERATE_TYPE_UPDATE)
	@ApiOperation(value = "迁移策略执行规则", notes = "迁移策略执行规则")
	@RequestMapping(value = "/update_scheduler_strategy_rule", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerUpdate_scheduler_strategy_rule" })
	@ParamSecurity(enabled = true)
	public void updateSchedulerStrategyRule(@Valid UpdateSchedulerStrategyRuleMsg config) throws Exception {
		service.updateSchedulerStrategyRule(config);
		StringBuffer buff = new StringBuffer();
    	buff.append("修改迁移策略执行规则，");
    	buff.append(config.toString());
		sysBaseAPI.addLog(buff.toString(), null, SysLogOperateType.UPDATE, null ,null , "");
	}

	@AutoLog(value = "查看迁移策略执行规则设置", operateType = CommonConstant.OPERATE_TYPE_DETAIL, module = "离线业务多数据中心迁移-多数据中心弹性迁移策略-迁移策略执行规则" )
	@ApiOperation(value = "获取迁移策略执行规则", notes = "获取迁移策略执行规则")
	@RequestMapping(value = "/get_scheduler_strategy_rule", method = RequestMethod.GET)
	@RequiresPermissions(value = { "schedulerGet_scheduler_strategy_rule" })
	@ParamSecurity(enabled = true)
	public SchedulerStrategyRuleVo getSchedulerStrategyRule() throws Exception {
		return service.getSchedulerStrategyRule();
	}

	// @AutoLog(value = "查看调度效果预测", operateType = CommonConstant.OPERATE_TYPE_DETAIL)
	@ApiOperation(value = "调度效果预测", notes = "调度效果预测")
	@RequestMapping(value = "/scheduler_effect_prediction", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerScheduler_effect_prediction" })
	@ParamSecurity(enabled = true)
	public SchedulerEffectPredictionVo schedulerEffectPrediction(@Valid SchedulerEffectPredictionMsg msg) throws Exception {
		sysBaseAPI.addLog("调度效果预测，应用资源ID："+msg.getAppId(), null, SysLogOperateType.DETAIL, null ,null , null);
		return service.schedulerEffectPrediction(msg);
	}

	// @AutoLog(value = "查看调度结果偏差分析", operateType = CommonConstant.OPERATE_TYPE_DETAIL)
	@ApiOperation(value = "调度结果偏差分析", notes = "调度结果偏差分析")
	@RequestMapping(value = "/scheduler_result_analysis", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerScheduler_result_analysis" })
	@ParamSecurity(enabled = true)
	public SchedulerResultAnalysisVo schedulerResultAnalysis(@Valid SchedulerResultAnalysisMsg msg) throws Exception {
		sysBaseAPI.addLog("查看调度结果偏差分析，应用资源ID："+msg.getAppId(), null, SysLogOperateType.DETAIL, null ,null , null);
		return service.schedulerResultAnalysis(msg);
	}

	@AutoLog(value = "迁移资源", operateType = CommonConstant.OPERATE_TYPE_UPDATE, module = "精确管控与供电制冷联动-统一管理联动平台-业务隔离")
	@ApiOperation(value = "迁移资源", notes = "迁移资源")
	@RequestMapping(value = "/migrate_resource", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerMigrate_resource" })
	@ParamSecurity(enabled = true)
	public void migrateResource(@Valid MigrateResourceVo msg) throws Exception {
		service.migrateResource(msg);
	}

	// 模拟接口
	@ApiOperation(value = "迁移虚拟机", notes = "迁移虚拟机")
	@RequestMapping(value = "/migrate_vm", method = RequestMethod.GET)
	@ParamSecurity(enabled = true)
	public boolean migrateVm(String id) throws Exception {
		return true;
	}

	// 模拟接口
	@ApiOperation(value = "迁移容器", notes = "迁移容器")
	@RequestMapping(value = "/migrate_k8s", method = RequestMethod.GET)
	@ParamSecurity(enabled = true)
	public boolean migrateK8s(String id) throws Exception {
		return true;
	}
	
	@ApiOperation(value = "调度建议列表", notes = "调度任务列表")
	@RequestMapping(value = "/job/advicePage", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerJobPage" })
	@ParamSecurity(enabled = true)
	public PageResult<SchedulerAdviceVo> advicePage(@Valid PageSchedulerAdviceMsg msg) throws Exception {
		PageResult<SchedulerAdviceVo> res = this.adviceService.advicePage(msg);
		return res;
	}
	
	@ApiOperation(value = "开启执行建议", notes = "开始执行建议")
	@RequestMapping(value = "/job/startAdvice", method = RequestMethod.POST)
	@RequiresPermissions(value = { "schedulerJobPage" })
	public void startAdvice(Long adviceId) throws Exception {
		this.adviceService.moveOneAdviceToJob(adviceId);
	}
	
	@ApiOperation(value = "手动迁移可迁移的数据中心", notes = "手动迁移可迁移的数据中心")
	@RequestMapping(value = "/aviableDatacenter", method = RequestMethod.POST)
	public List<DatacenterResourceVo> aviableDatacenter(AviableDatacenterMsg msg) throws Exception {
		return this.adviceService.aviableDatacenter(msg);
	}
	
	
	@ApiOperation(value = "手动迁移可迁移的数据中心", notes = "开始执行建议")
	@RequestMapping(value = "/startJob", method = RequestMethod.POST)
	public void aviableDatacenter(StartJobMsg msg) throws Exception {

		adviceService.startJob(msg);
		
	}
	
	@ApiOperation(value = "调度总览", notes = "调度总览")
	@RequestMapping(value = "/overview", method = RequestMethod.POST)
	public SchedulerOverview overview() throws Exception {
		return adviceService.overview();
		
	}
	
	
}
